﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "servermap.h"
#include "ServerConsole.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CCommonHandler
UInt CCommonHandler::OnHandle(Int nEvent, uintptr_t utData, ULLong ullParam)
{
    switch (nEvent)
    {
    case PAKE_LIVE:
        {
            OnLive(utData != false);
        }
        break;
    case PAKE_LINK:
        {
            OnLink((Int)ullParam, utData);
        }
        break;
    case PAKE_UPDATE:
        {
            OnUpdate((Int)ullParam, utData);
        }
        break;
    case PAKE_SYNC:
        {
            OnSync((Int)ullParam, utData);
        }
        break;
    case PAKE_UNLINK:
        {
            OnUnlink((Int)ullParam, utData);
        }
        break;
    case PAKT_CENTER:
    case PAKT_BALANCE:
    case PAKT_AUTHORDB:
    case PAKT_AUTHOR:
    case PAKT_MASTERDB:
    case PAKT_MASTER:
    case PAKT_SERVICE:
    case PAKT_GATE:
        {
            SetServer(reinterpret_cast<ICommonServer*>(utData));
        }
        break;
    default:
        {
            //assert(0);
        }
    }
    return RET_OKAY;
}

UInt CCommonHandler::OnHandle(Int, CEventBase&, ULLong)
{
    return RET_OKAY;
}

UInt CCommonHandler::OnHandle(Int nEvent, CStream& Stream, ULLong ullParam)
{
    if (nEvent == PAKE_SYNC)
    {
        OnSync((Int)ullParam, Stream);
    }
    return RET_OKAY;
}

UInt CCommonHandler::OnHandle(Int, UInt)
{
    assert(m_pServer != nullptr);
    if (m_pServer->Update() == RET_OKAY)
    {
        ++m_nLoop;
        if (m_nLoop > UPDATE_INFO_TIME)
        {
            m_nLoop = 0;
            if (m_nDiff >= UPDATE_INFO_DIFF)
            {
                m_nDiff = 0;
                UpdateServerInfo();
            }
            else
            {
                ++m_nDiff;
            }
        }
    }
    return RET_OKAY;
}

bool CCommonHandler::AddServerData(Int nServerIndex, uintptr_t utData)
{
    ++m_nDiff;

    CStringFix strTemp;
    strTemp  = GetName();
    strTemp += TF("Link---");
    strTemp += GServerConsoleInst->GetServerName(nServerIndex);

    assert(utData != 0);
    SVR_COMMON_MAP::PSVR_PAIR pPair = reinterpret_cast<SVR_COMMON_MAP::PSVR_PAIR>(utData);
    assert(pPair->Value.usStatus & STATUSU_LINK);

    strTemp.AppendFormat(TF("[Key=%p, ServerId=%d, %d/%d, Load="), pPair->ullKey, pPair->Value.usId, pPair->Value.uTotal, pPair->Value.uOnline);
    if (pPair->Value.usLoad <= DATAD_OVER_LOAD)
    {
        strTemp.AppendFormat(TF("%d%%]"), (pPair->Value.usLoad / DATAD_TOPERCENT));
    }
    else if (pPair->Value.usLoad < DATAD_MAY_DAY)
    {
        strTemp += TF("Warn]");
    }
    else
    {
        strTemp += TF("Mayday]");
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);

    AddServerDataAddr(nServerIndex, pPair->Value.NetAddr);
    return true;
}

bool CCommonHandler::UpdateServerData(Int nServerIndex, uintptr_t utData)
{
    ++m_nDiff;

    CStringFix strTemp;
    strTemp  = GetName();
    strTemp += TF("Update---");
    strTemp += GServerConsoleInst->GetServerName(nServerIndex);

    assert(utData != 0);
    SVR_COMMON_MAP::PSVR_PAIR pPair = reinterpret_cast<SVR_COMMON_MAP::PSVR_PAIR>(utData);
    assert(pPair->Value.usStatus & (STATUSU_SYNC | STATUSU_LINK));

    strTemp.AppendFormat(TF("[Key=%p, ServerId=%d, %d/%d, Load="), pPair->ullKey, pPair->Value.usId, pPair->Value.uTotal, pPair->Value.uOnline);
    if (pPair->Value.usLoad <= DATAD_OVER_LOAD)
    {
        strTemp.AppendFormat(TF("%d%%]"), (pPair->Value.usLoad / DATAD_TOPERCENT));
    }
    else if (pPair->Value.usLoad < DATAD_MAY_DAY)
    {
        strTemp += TF("Warn]");
    }
    else
    {
        strTemp += TF("Mayday]");
    }
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
    return true;
}

bool CCommonHandler::RemoveServerData(Int nServerIndex, uintptr_t utData)
{
    ++m_nDiff;

    CStringFix strTemp;
    strTemp  = GetName();
    strTemp += TF("Unlink---");
    strTemp += GServerConsoleInst->GetServerName(nServerIndex);

    strTemp.AppendFormat(TF("[Key=%p]"), utData);
    LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
    return true;
}

void CCommonHandler::AddServerDataAddr(Int nServerIndex, void* pAddr)
{
    CStringFix strTemp;
    strTemp  = GetName();
    strTemp += TF("Addr---");
    strTemp += GServerConsoleInst->GetServerName(nServerIndex);
    strTemp += TF("===");

    CNetAddr* pNetAddr = reinterpret_cast<CNetAddr*>(pAddr);

    CStrAddr strAddr;

    switch (nServerIndex)
    {
    case PAKT_BALANCE:
        {
            // udp
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("UDP Ext-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
        }
        break;
    case PAKT_AUTHORDB:
        {
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("TCP Int-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
        }
        break;
    case PAKT_AUTHOR:
        {
            // tcp
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("TCP Ext-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // udp
            ++pNetAddr;
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF(", UDP Int-Listen Master=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // authordb
            ++pNetAddr;
            if (pNetAddr->usPort != 0)
            {
                GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
                strTemp.AppendFormat(TF(", TCP Int-Connect Author DB=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
                LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
            }
        }
        break;
    case PAKT_MASTERDB:
        {
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("TCP Int-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
        }
        break;
    case PAKT_MASTER:
        {
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF(", TCP Int-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // udp
            ++pNetAddr;
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF(", UDP Int-Listen Author=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // masterdb
            ++pNetAddr;
            if (pNetAddr->usPort != 0)
            {
                GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
                strTemp.AppendFormat(TF(", TCP Int-Connect Master DB=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
                LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
            }
        }
        break;
    case PAKT_SERVICE:
        {
            // master
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("TCP Int-Connect Master=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // masterdb
            ++pNetAddr;
            if (pNetAddr->usPort != 0)
            {
                GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
                strTemp.AppendFormat(TF(", TCP Int-Connect Master DB=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
                LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
            }
        }
        break;
    case PAKT_GATE:
        {
            // tcp
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF("TCP-UDP Ext-Listen=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            // udp
            ++pNetAddr;
            GServerConsoleInst->m_NetworkPtr->TranslateAddr(strAddr.strIp, strAddr.usPort, *pNetAddr, false);
            strTemp.AppendFormat(TF(", UDP Int-Listen Author=[%s]:%d"), *strAddr.strIp, strAddr.usPort);
            LOG_INFO(GServerConsoleInst->m_FileLog, *strTemp);
        }
        break;
    default:
        {
        }
    }
}





